package com.zxd.interview.register.version1.server.core;

import lombok.Data;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;

/**
 * 代表了一个服务实例
 * 里面包含了一个服务实例的所有信息
 * 比如说服务名称、ip地址、hostname、端口号、服务实例id
 * 还有就是契约信息（Lease）
 *
 * @author xander
 */
@Data
@ToString
@Slf4j
public class ServiceInstance {

    /**
     * 判断一个服务实例不再存活的周期
     */
    private static final Long NOT_ALIVE_PERIOD = 90 * 1000L;

    /**
     * 服务名称
     */
    private String serviceName;
    /**
     * ip地址
     */
    private String ip;
    /**
     * 主机名
     */
    private String hostname;
    /**
     * 端口号
     */
    private int port;
    /**
     * 服务实例id
     */
    private String serviceInstanceId;
    /**
     * 契约
     */
    private Lease lease;

    public ServiceInstance() {
        this.lease = new Lease();
    }

    /**
     * 服务续约
     */
    public void renew() {
        if (this.lease != null) {
            this.lease.renew();
        }
    }

    /**
     * 服务实例是否存活
     *
     * @return
     */
    public Boolean isAlive() {
        return this.lease.isAlive();
    }

    /**
     * 契约
     * 维护了一个服务实例跟当前的这个注册中心之间的联系
     * 包括了心跳的时间，创建的时间，等等
     *
     * @author xander
     */
    private class Lease {

        /**
         * 最近一次心跳的时间
         */
        private volatile Long latestHeartbeatTime = System.currentTimeMillis();

        /**
         * 续约，你只要发送一次心跳，就相当于把register-client和register-server之间维护的一个契约
         * 进行了续约，我还存活着，我们俩的契约可以维持着
         *
         * @param
         */
        public void renew() {
            this.latestHeartbeatTime = System.currentTimeMillis();
            log.info("服务实例【" + serviceInstanceId + "】，进行续约：" + latestHeartbeatTime);
        }

        /**
         * 判断当前服务实例的契约是否还存活
         *
         * @return
         */
        public Boolean isAlive() {
            Long currentTime = System.currentTimeMillis();
            if (currentTime - latestHeartbeatTime > NOT_ALIVE_PERIOD) {
                log.info("服务实例【" + serviceInstanceId + "】，不再存活");
                return false;
            }
            log.info("服务实例【" + serviceInstanceId + "】，保持存活");
            return true;
        }

    }


}
